home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 2
/
Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso
/
Aminet
/
dev
/
gcc
/
bmake15.lzh
/
cond.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-10-27
|
6KB
|
286 lines
/* cond.c
* (c) Copyright 1991 by Ben Eng, All Rights Reserved
*
*/
#include <ctype.h>
#include <clib/exec_protos.h>
#include <fcntl.h>
#include "make.h"
#include "depend.h"
#include "cond.h"
/* binary search to find the function */
struct drctvs *
find_drctvs( struct drctvs *array, int array_size, char *name )
{
int first = 0;
int last = array_size - 1;
int mid;
int diff, len;
/* binary search */
while( first <= last ) {
mid = (first+last) / 2;
len = strlen( array[ mid ].directive );
diff = strnicmp( name, array[ mid ].directive, len );
if( !diff )
return( &array[ mid ] ); /* found */
if( first == last )
break; /* not found */
if( diff < 0 )
last = mid - 1;
else
first = mid + 1;
}
return( NULL ); /* not found */
}
int
push_state( struct List *stack, long state )
{
struct mstate *new = (struct mstate *)malloc( sizeof(struct mstate));
if( !new )
return( 1 ); /* no memory */
new->node.ln_Type = NT_USER;
new->state = state;
AddHead( stack, &new->node );
return( 0 );
}
int
pop_state( struct List *stack )
{
struct mstate *new = (struct mstate *)RemHead( stack );
int state;
if( !new )
return( 0 ); /* no state */
state = new->state;
free( new );
return( state );
}
void
clear_stack( struct List *stack )
{
struct Node *node, *succ;
for( node = stack->lh_Head; node->ln_Succ; node = succ ) {
succ = node->ln_Succ;
free( node );
}
NewList( stack );
}
/* returns true if we are still within a conditional */
int
get_directive_state( struct List *stack )
{
struct mstate *first = (struct mstate *)stack->lh_Head;
if( !first->node.ln_Succ )
return( 0 );
return( first->state );
}
/* conditions return 0 for false, 1 for true, -1 for error */
int
do_condeq( char *string, int negate )
{
char *exp1 = NULL, *exp2 = NULL;
char *lparen = string, *comma, *rparen;
int retval = -1; /* default to error */
exp1 = (char *)malloc( Param.MaxLine );
exp2 = (char *)malloc( Param.MaxLine );
if( !exp1 || !exp2 )
goto death;
while( *lparen && *lparen != '(' )
lparen++;
if( *lparen != '(' )
goto death;
comma = lparen + 1;
while( *comma && *comma != ',' )
comma++;
if( *comma != ',' )
goto death;
rparen = comma + 1;
while( *rparen && *rparen != ')' )
rparen++;
if( *rparen != ')' )
goto death;
*comma = *rparen = (char)0;
if( expand_macros( exp1, lparen + 1, Param.MaxLine ) ||
expand_macros( exp2, comma + 1, Param.MaxLine ))
goto death;
if( negate )
retval = stricmp( exp1, exp2 ) ? 1 : 0; /* set condition code */
else
retval = stricmp( exp1, exp2 ) ? 0 : 1; /* set condition code */
death:
if( exp1 )
free( exp1 );
if( exp2 )
free( exp2 );
return( retval );
}
int
do_conddef( char *string, int negate )
{
char *lparen = string, *rparen;
int retval = -1; /* default to error */
while( *lparen && *lparen != '(' )
lparen++;
if( *lparen != '(' )
goto death;
rparen = lparen + 1;
while( *rparen && *rparen != ')' )
rparen++;
if( *rparen != ')' )
goto death;
*rparen = (char)0;
retval = find_macro( lparen + 1 ) ? 1 : 0;
if( negate )
retval = retval ? 0 : 1;
death:
return( retval );
}
int
do_condexists( char *string, int negate )
{
char *lparen = string, *rparen;
int retval = -1; /* default to error */
while( *lparen && *lparen != '(' )
lparen++;
if( *lparen != '(' )
goto death;
rparen = lparen + 1;
while( *rparen && *rparen != ')' )
rparen++;
if( *rparen != ')' )
goto death;
*rparen = (char)0;
retval = access( lparen + 1, 0 ) ? 0 : 1;
if( negate )
retval = retval ? 0 : 1;
death:
return( retval );
}
int
cdrctv_eq( char *string )
{
return( do_condeq( string, 0 ));
}
int
cdrctv_neq( char *string )
{
return( do_condeq( string, 1 ));
}
int
cdrctv_def( char *string )
{
return( do_conddef( string, 0 ));
}
int
cdrctv_ndef( char *string )
{
return( do_conddef( string, 1 ));
}
int
cdrctv_exists( char *string )
{
return( do_condexists( string, 0 ));
}
int
cdrctv_nexists( char *string )
{
return( do_condexists( string, 1 ));
}
/* keep it sorted for binary search */
struct drctvs carray[ MAX_CDRCTVS ] = {
{ "def", cdrctv_def },
{ "eq", cdrctv_eq },
{ "exists", cdrctv_exists },
{ "ndef", cdrctv_ndef },
{ "neq", cdrctv_neq },
{ "nexists", cdrctv_nexists }
};
int
drctv_else( char *string, struct List *stack )
{
int state = pop_state( stack );
int newstate = 0;
if( state != STATE_IF_T && state != STATE_IF_F ) {
logfile( "ERROR: else with no matching conditional\n" );
return( 1 );
}
newstate = (state == STATE_IF_T) ? STATE_EL_T : STATE_EL_F;
debugprintf( 4, ("else changes state from %d to %d\n",
state, newstate ));
push_state( stack, newstate );
return( 0 );
}
int
drctv_endif( char *string, struct List *stack )
{
int state = pop_state( stack );
if( !state ) {
logfile( "ERROR: endif with no matching conditional\n" );
return( 1 );
}
return( 0 );
}
int
drctv_if( char *string, struct List *stack )
{
struct drctvs *cdrctv;
int condition;
while( isspace( *string )) string++;
if( !*string ) {
logfile( "No condition given\n" );
return( 1 );
}
if( cdrctv = find_drctvs( carray, MAX_CDRCTVS, string )) {
debugprintf( 4, ("condition %s\n", string ));
condition = (*cdrctv->call)( string + strlen( cdrctv->directive ));
debugprintf( 4, ("condition returns %d\n", condition ));
if( condition < 0 ) {
logprintf( "Error in condition: %s\n", string );
return( 1 );
}
else {
push_state( stack, ( condition ? STATE_IF_T : STATE_IF_F ));
return( 0 );
}
}
logprintf( "Unrecognized condition: %s\n", string );
return( 1 );
}